//
//  VVXMPPManager.m
//  VVWenxinChat
//
//  Created by 王惠平 on 2017/5/10.
//  Copyright © 2017年 will wang. All rights reserved.
//

#import "VVXMPPManager.h"
#import "XMPPLogging.h"
#import "DDLog.h"
#import "DDTTYLogger.h" //（发送日志语句到控制台）

static VVXMPPManager *_instance;

@interface VVXMPPManager () <XMPPStreamDelegate,XMPPAutoPingDelegate,XMPPReconnectDelegate,XMPPRosterDelegate>

//数据流对象  封装socket
@property (nonatomic, strong) XMPPStream *xmppStream;

//密码
@property (nonatomic, strong) NSString *passWord;

//注册账号
@property (nonatomic, assign) BOOL registeAccount;

//心跳检测模块
@property (nonatomic, strong) XMPPAutoPing *xmppAutoping;

//自动重连模块
@property (nonatomic, strong) XMPPReconnect *xmppReconect;



@end

@implementation VVXMPPManager

+ (instancetype)sharedManager {
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        _instance = [VVXMPPManager new];
        
        //设置日志
        [_instance setupLogin];
    
        //设置模块
        [_instance setupModules];
    
    });
    
    return _instance;
}

//设置模块
- (void) setupModules {
    
    /**
     * 使用模块的一般步骤: 1.创建模块 2.设置属性/代理 3.激活模块
     */
    
    /**
     * 心跳包
     */
    
    //设置属性
    //设置心跳包间隔
    self.xmppAutoping.pingInterval = 5;
    
    //设置心跳超时时长
    self.xmppAutoping.pingTimeout = 5;
    
    //设置是否响应对端发送来的心跳包
    self.xmppAutoping.respondsToQueries = YES;
    
    //激活模块
//    [self.xmppAutoping activate:self.xmppStream];
  
    /**
     * 自动重连模块
     */
    //    [self.xmppReconnect activate:self.xmppStream];
    
    /**
     * 花名册模块
     */

    //自动获取服务端保存的联系人列表
    self.xmppRoster.autoFetchRoster = YES;
    
    //设置当连接断开时,是否清空内存中记录的联系人及其在线设备数据
//    self.xmppRoster.autoClearAllUsersAndResources = YES;
    
    //设置是否自动接受好友请求
    self.xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = NO;
    
    //设置自动清空本地数据库为NO;
    [XMPPRosterCoreDataStorage sharedInstance].autoRemovePreviousDatabaseFile = NO;
    
    [self.xmppRoster activate:self.xmppStream];
    
    
}

//设置日志
- (void) setupLogin {

    //设置xml数据的打印日志
    [DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV];
}

//注册
- (void)registerWithJID:(XMPPJID *)jid andPassword:(NSString *)passWord {

    //设置标记
    self.registeAccount = YES;
    
    //注册 连接服务器
    [self connectWithJID:jid andPassword:passWord];
    
}

//登录
- (void)loginWithJID:(XMPPJID *)jid andPassword:(NSString *)passWord {
    
    //登录 连接服务器
    [self connectWithJID:jid andPassword:passWord];
}

- (void)connectWithJID:(XMPPJID *)jid andPassword:(NSString *)passWord {
    
    //设置ip地址&端口号&jid
    self.xmppStream.hostName = @"127.0.0.1";
    self.xmppStream.hostPort = 5222;
    self.xmppStream.myJID = jid;
    self.passWord = passWord;
    
    //建立连接
    [self.xmppStream connectWithTimeout:-1 error:nil];
    
}
//已经接收到出行订阅请求后调用
- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence {
    
    XMPPUserCoreDataStorageObject *userCDObj = [[XMPPRosterCoreDataStorage sharedInstance] userForJID:presence.from xmppStream:self.xmppStream managedObjectContext:[XMPPRosterCoreDataStorage sharedInstance].mainThreadManagedObjectContext];
    
    if ([userCDObj.subscription isEqualToString:@"to"]) {
        
         UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"好友通知" message:[NSString stringWithFormat:@"成功添加%@为好友", presence.from.user] preferredStyle:UIAlertControllerStyleAlert];
        
        //同意对方的订阅
        [self.xmppRoster acceptPresenceSubscriptionRequestFrom:presence.from andAddToRoster:YES];
        
        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertVC animated:YES completion:^{
           
            //隐藏弹窗
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                
                [alertVC dismissViewControllerAnimated:YES completion:nil];
            });
            
        }];
    } else { //被别人加好友
        
        //接收到好友请求后.应该让用户选择是否接收好友的请求
        UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"好友请求" message:[NSString stringWithFormat:@"收到来自%@的好友请求", presence.from.user] preferredStyle:UIAlertControllerStyleAlert];
        
        //添加动作
        UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"同意" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
            //接受好友请求
            [self.xmppRoster acceptPresenceSubscriptionRequestFrom:presence.from andAddToRoster:YES];
        }];
        
        UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"拒绝" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            
            //拒绝好友请求
            [self.xmppRoster rejectPresenceSubscriptionRequestFrom:presence.from];
        }];
        [alertVC addAction:action1];
        [alertVC addAction:action2];
        //展示弹窗
        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertVC animated:YES completion:nil];
    }
}

#pragma mark - XMPPReconnectDelegate

//已经检测出异常断开后调用
- (void)xmppReconnect:(XMPPReconnect *)sender didDetectAccidentalDisconnect:(SCNetworkConnectionFlags)connectionFlags{
    
    NSLog(@"异常断开");
    
}


/**
 设置是否执行自动重连
 
 @param sender 模块
 @param connectionFlags 网络请求
 @return 设置是否执行自动重连    systemconfiguration 检测网络情况 c语言类库  AFN集成iOS的系统类库ReachAbility(集成systemconfiguration)来实现网络检测
 */
- (BOOL)xmppReconnect:(XMPPReconnect *)sender shouldAttemptAutoReconnect:(SCNetworkConnectionFlags)connectionFlags{
    
    
    return YES;
}

#pragma mark - XMPPAutoPingDelegate

//已经发送心跳包后调用
- (void)xmppAutoPingDidSendPing:(XMPPAutoPing *)sender {
    
    NSLog(@"发送心跳包");
}

//已经接受到心跳包的响应后调用
- (void)xmppAutoPingDidReceivePong:(XMPPAutoPing *)sender {
    
    NSLog(@"接收到心跳包");
}

//心跳包超时后调用
- (void)xmppAutoPingDidTimeout:(XMPPAutoPing *)sender {
    
    NSLog(@"连接异常");
}

#pragma  mark - XMPPStreamDelegate

//客户端连接到服务器后调用
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
    
    NSLog(@"连接建立");
    
    //区分登录/注册
    if (self.registeAccount) {
        
        //提交账号信息
        [self.xmppStream registerWithPassword:self.passWord error:nil];
        
    } else {
        
        //认证密码
        [self.xmppStream authenticateWithPassword:self.passWord error:nil];
    }
    
}

//注册成功调用
- (void)xmppStreamDidRegister:(XMPPStream *)sender {
    
    NSLog(@"注册成功");
}

//登录成功后调用
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
    
    NSLog(@"用户登录成功");
    
    //设置在线状态
    XMPPPresence *presence = [XMPPPresence presence];
    
    //设置预置状态(添加show的子元素)
    [presence addChild:[DDXMLNode elementWithName:@"show" stringValue:@"dnd"]];
     
    //设置自定义状态 必须先设置预置状态
    [presence addChild:[DDXMLNode elementWithName:@"status" stringValue:@"最近比较忙~"]];
    
    //发送presence节给服务器
    [self.xmppStream sendElement:presence];
    
    UIStoryboard *rootSB = [UIStoryboard storyboardWithName:@"Root" bundle:nil];
    
    UITabBarController *tabBarVC = [rootSB instantiateInitialViewController];
    
    [UIApplication sharedApplication].keyWindow.rootViewController = tabBarVC;
    
}

//懒加载
- (XMPPStream *)xmppStream {
    
    if (_xmppStream == nil) {
        
        _xmppStream = [[XMPPStream alloc]init];
        
        //监听socker状态
        [_xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    
    return _xmppStream;
}

- (XMPPAutoPing *)xmppAutoping {
    
    if (_xmppAutoping == nil) {
        
        _xmppAutoping = [[XMPPAutoPing alloc]initWithDispatchQueue:dispatch_queue_create(0, 0)];
        
        //设置代理 监听心跳包情况
        [_xmppAutoping addDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    
    return _xmppAutoping;
}

- (XMPPReconnect *)xmppReconect {
    
    if (_xmppReconect == nil) {
        
        _xmppReconect = [[XMPPReconnect alloc]initWithDispatchQueue:dispatch_get_main_queue()];
        
        //设置代理  监听网络请求,设置是否进行自动重连
        [_xmppReconect addDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    
    return _xmppReconect;
}

- (XMPPRoster *)xmppRoster{
    if (_xmppRoster == nil) {
        
        _xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:[XMPPRosterCoreDataStorage sharedInstance] dispatchQueue:dispatch_get_main_queue()];
        //设置代理 监听好友请求
        [_xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    return _xmppRoster;
}

@end
